package com.ruoyi.app.service.impl

import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.util.StrUtil
import cn.hutool.json.JSONUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.shaun.core.context.ProfileHolder
import com.ruoyi.app.common.*
import com.ruoyi.app.domain.dto.ImageChangeFaceDto
import com.ruoyi.app.domain.dto.MyRecordDto
import com.ruoyi.app.domain.dto.MyRecordSearchDto
import com.ruoyi.app.domain.dto.VideoChangeFaceDto
import com.ruoyi.app.domain.vo.FunctionIndexVo
import com.ruoyi.app.domain.vo.SingleTemplateMemberInfo
import com.ruoyi.app.domain.vo.UserRecordListVo
import com.ruoyi.app.service.RecordApiService
import com.ruoyi.back.domain.*
import com.ruoyi.back.domain.Function
import com.ruoyi.back.domain.v3.VideoSinglePriceService
import com.ruoyi.back.domain.v4.ContentSourceCheck
import com.ruoyi.back.domain.v4.ContentSourceCheckSetting
import com.ruoyi.back.enums.UserTypeEnum
import com.ruoyi.back.mapper.AppUserSettingMapper
import com.ruoyi.back.mapper.ChannelFreeTemplateMapper
import com.ruoyi.back.mapper.ContentSourceCheckMapper
import com.ruoyi.back.mapper.ContentSourceCheckSettingMapper
import com.ruoyi.back.service.*
import com.ruoyi.back.v1.service.GlobalParamDetailService
import com.ruoyi.exception.FlyException
import com.ruoyi.mq.ChangeFaceTaskManager
import com.ruoyi.util.changePicFace
import com.ruoyi.util.changeVideoFace
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*

@Service
class RecordApiServiceImpl : RecordApiService {

    @Autowired
    private lateinit var userRecordService: UserRecordService

    @Autowired
    private lateinit var recommendService: TemplateRecommendService

    @Autowired
    private lateinit var templateService: TemplateService

    @Autowired
    private lateinit var functionService: FunctionService

    @Autowired
    private lateinit var netUrlUploadOss: NetUrlUploadOss

    @Autowired
    private lateinit var appUserService: AppUserService

    @Autowired
    private lateinit var userCollectService: UserCollectService

    @Autowired
    private lateinit var channelManagerService: ChannelManagerService

    @Autowired
    private lateinit var templateCategoryService: TemplateCategoryService

    @Autowired
    private lateinit var userMemberService: UserMemberService

    @Autowired
    private lateinit var videoSinglePriceService: VideoSinglePriceService

    @Autowired
    private lateinit var memberService: MemberService

    @Autowired
    private lateinit var channelFreeTemplateMapper: ChannelFreeTemplateMapper

    @Autowired
    private lateinit var channelFunctionService: ChannelFunctionService

    @Autowired
    private lateinit var userSettingMapper: AppUserSettingMapper

    @Autowired
    private lateinit var contentSourceCheckSettingMapper: ContentSourceCheckSettingMapper

    @Autowired
    private lateinit var contentSourceCheckMapper: ContentSourceCheckMapper

    @Autowired
    private lateinit var huoshanApi: HuoshanApi

    @Autowired
    private lateinit var globalParamDetailService: GlobalParamDetailService

    @Autowired
    private lateinit var changeFaceTaskManager: ChangeFaceTaskManager

    private val log = LoggerFactory.getLogger(RecordApiServiceImpl::class.java)

    fun booleanToll(channelCode: String) = channelManagerService.getOne(
        KtQueryWrapper(ChannelManager::class.java)
            .eq(ChannelManager::code, channelCode)
    )
        ?.charge ?: true

    override fun booleanSoftWatermark(channelCode: String): Boolean {

        var result = false
        channelManagerService.getOne(
            KtQueryWrapper(ChannelManager::class.java)
                .eq(ChannelManager::code, channelCode)
        )
            ?.let { channelManager ->
                functionService.getOne(
                    KtQueryWrapper(Function::class.java)
                        .eq(Function::name, "APP名称水印")
                )
                    ?.let { function ->
                        channelFunctionService.getOne(
                            KtQueryWrapper(ChannelFunction::class.java)
                                .eq(ChannelFunction::channelId, channelManager.id)
                                .eq(ChannelFunction::functionId, function.id)
                        )
                            ?.let {
                                userSettingMapper.selectOne(
                                    KtQueryWrapper(AppUserSetting::class.java)
                                        .eq(AppUserSetting::userId, ProfileHolder.getProfile().id)
                                )
                                    ?.let { appUserSetting ->
                                        result = appUserSetting.softWatermark ?: false
                                    }
                            }
                    }
            }
        return result
    }

    override fun booleanAiWatermark(channelCode: String): Boolean {
        var result = false
        channelManagerService.getOne(
            KtQueryWrapper(ChannelManager::class.java)
                .eq(ChannelManager::code, channelCode)
        )
            ?.let { channelManager ->
                functionService.getOne(
                    KtQueryWrapper(Function::class.java)
                        .eq(Function::name, "AI生成水印")
                )
                    ?.let { function ->
                        channelFunctionService.getOne(
                            KtQueryWrapper(ChannelFunction::class.java)
                                .eq(ChannelFunction::channelId, channelManager.id)
                                .eq(ChannelFunction::functionId, function.id)
                        )
                            ?.let {
                                userSettingMapper.selectOne(
                                    KtQueryWrapper(AppUserSetting::class.java)
                                        .eq(AppUserSetting::userId, ProfileHolder.getProfile().id)
                                )
                                    ?.let { appUserSetting ->
                                        result = appUserSetting.aiWatermark ?: false
                                    }
                            }
                    }
            }
        return result
    }

    override fun booleanHideWatermark(channelCode: String): Boolean =
        (channelManagerService.getOne(
            KtQueryWrapper(ChannelManager::class.java)
                .eq(ChannelManager::code, channelCode)
        )
            ?.let { channelManager ->
                functionService.getOne(
                    KtQueryWrapper(Function::class.java)
                        .eq(Function::name, "隐式水印")
                )
                    ?.let { function ->
                        channelFunctionService.getOne(
                            KtQueryWrapper(ChannelFunction::class.java)
                                .eq(ChannelFunction::channelId, channelManager.id)
                                .eq(ChannelFunction::functionId, function.id)
                        )
                    }
            }) != null

    override fun getUserRecordList(myRecordSearchDto: MyRecordSearchDto): Data<List<FunctionIndexVo>> =
        Ok("获取我的作品数据成功", myRecordSearchDto.functionId?.run {

            listOf(
                if (myRecordSearchDto.functionId == -1L) {
                    FunctionIndexVo().apply {
                        id = -1L
                        name = "全部"
                        userRecordList = recordListByFunctionId(myRecordSearchDto)
                    }
                } else {
                    functionService.getById(this)?.let {
                        FunctionIndexVo().apply {
                            id = it.id
                            name = it.name
                            userRecordList = recordListByFunctionId(myRecordSearchDto)
                        }
                    } ?: FunctionIndexVo()
                }

            )

        } ?: kotlin.run {

            functionService.appFunctionIndex().run {
                map {
                    it.apply {
                        userRecordList = recordListByFunctionId(myRecordSearchDto.apply {
                            functionId = it.id
                        })
                    }
                }
            }
        })

    fun recordListByFunctionId(myRecordSearchDto: MyRecordSearchDto): PageMp<UserRecordListVo> =
        userRecordService.page(
            Page(myRecordSearchDto.pageNum!!, myRecordSearchDto.pageSize!!),
            KtQueryWrapper(UserRecord::class.java).eq(
                (myRecordSearchDto.functionId != null) && (myRecordSearchDto.functionId != -1L),
                UserRecord::functionId,
                myRecordSearchDto.functionId
            ).eq(UserRecord::createBy, ProfileHolder.getProfile().id.toLong())
                .eq(UserRecord::deleteTag, 0)
                .orderByDesc(UserRecord::createTime)
        ).let { page: Page<UserRecord> ->

            Page<UserRecordListVo>().apply {
                BeanUtil.copyProperties(page, this)
                records = page.records.takeIf { it.isNotEmpty() }?.run {
                    map {
                        UserRecordListVo().apply {
                            id = it.id
                            url = it.url
                            status = it.status
                            errorMsg =
                                it.errorMsg?.run {
                                    if (this.contains("输入图像未检测到人脸")) "未检测到人脸" else if (this.contains(
                                            "输入图像含有敏感或违规信息"
                                        )
                                    ) "含有敏感或违规信息" else this
                                }
                            title = templateService.getById(it.templateId)?.title
                            collect = it.templateId?.run { userCollectService.isCollect(it.createBy!!, this) } ?: false
                            cover = templateService.getById(it.templateId)?.cover
                            recommend = recommendService.recordBoolRecommend(it.id!!)
                        }
                    }
                }
            }.format()
        }


    override fun addUserVideoChangeFace(videoChangeFaceDto: VideoChangeFaceDto): Data<Boolean> =
        appUserService.getById(ProfileHolder.getProfile().id).run {

            videoChangeFaceDto.aiWatermark = booleanAiWatermark(videoChangeFaceDto.channelCode!!)
            videoChangeFaceDto.softWatermark = booleanSoftWatermark(videoChangeFaceDto.channelCode!!)
            videoChangeFaceDto.hideWatermark = booleanHideWatermark(videoChangeFaceDto.channelCode!!)
            if ((videoChangeFaceDto.templateId?.run { templateCategoryService.isTest(templateService.getById(this)?.categoryId) } ?: false) == false
            ) {

                if (StrUtil.isNotBlank(videoChangeFaceDto.localTemplateUrl) || channelFreeTemplateMapper.selectOne(
                        KtQueryWrapper(ChannelFreeTemplate::class.java)
                            .eq(
                                ChannelFreeTemplate::channelId, channelManagerService.getOne(
                                    KtQueryWrapper(ChannelManager::class.java)
                                        .eq(ChannelManager::code, videoChangeFaceDto.channelCode)
                                )?.id
                            )
                            .eq(ChannelFreeTemplate::templateId, videoChangeFaceDto.templateId)
                            .eq(ChannelFreeTemplate::templateType, 1)
                    ) == null
                ) {

                    if (singleVideoPay == null || singleVideoPay == false) {
                        if (userMemberService.getUserMemberByUserId(ProfileHolder.getProfile().id.toLong())?.endMemberDate?.year()
                                ?.let { it > 2100 } != true
                        ) {

                            if (booleanToll(videoChangeFaceDto.channelCode!!)) {
                                if ((videoChangeFaceDto.pay == true).not()) {
                                    if (userType != UserTypeEnum.MEMBER.code) {
                                        when (userType) {
                                            UserTypeEnum.NORMAL.code -> throw FlyException("换脸次数不足!")
                                            else -> throw FlyException("换脸次数不足!")
                                        }
                                    } else if ((totalChangeFaceCount ?: 0) - (changeFaceRemainCount ?: 0) <= 0) {
                                        throw FlyException("换脸次数不足!")
                                    }
                                }
                            }
                        }
                    }
                }


            }
            Ok("提交视频换脸任务成功", videoChangeFaceDto.let {

                val userRecord = UserRecord()
                userRecordService.save(userRecord.apply {

                    try {
                        contentSourceCheckSettingMapper.selectOne(
                            KtQueryWrapper(ContentSourceCheckSetting::class.java)
                                .eq(ContentSourceCheckSetting::type, 2)
                                .last("limit 1")
                        )
                            ?.run {
                                if (this.open == true) {
                                    videoChangeFaceDto.referenceUrl?.run {
                                        picContentCheck(this).let { results ->
                                            if (results.first().pass == true) {

                                                contentSourceCheckMapper.insert(ContentSourceCheck()
                                                    .apply {
                                                        appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                            ?.let {
                                                                createBy = it.id
                                                                username = it.username
                                                                userId = it.userId
                                                                type = 2
                                                                checkStatus = 2
                                                                source = videoChangeFaceDto.referenceUrl
                                                            }
                                                    })
                                            } else {
                                                contentSourceCheckMapper.insert(ContentSourceCheck()
                                                    .apply {
                                                        appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                            ?.let {
                                                                createBy = it.id
                                                                username = it.username
                                                                userId = it.userId
                                                                type = 2
                                                                checkStatus = 3
                                                                source = videoChangeFaceDto.referenceUrl
                                                                text = results.map { it.errorMsg }.joinToString(",")
                                                            }
                                                    })
                                                throw FlyException(results.map { it.errorMsg }.joinToString(","))
                                            }
                                        }
                                    }

                                    videoChangeFaceDto.faces?.run {
                                        JSONUtil.parseArray(this).forEach {
                                            JSONUtil.parseObj(it).getStr("imageUrl")
                                                ?.let { pic ->
                                                    picContentCheck(pic).let { results ->
                                                        if (results.first().pass == true) {

                                                            contentSourceCheckMapper.insert(ContentSourceCheck()
                                                                .apply {
                                                                    appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                                        ?.let {
                                                                            createBy = it.id
                                                                            username = it.username
                                                                            userId = it.userId
                                                                            type = 2
                                                                            checkStatus = 2
                                                                            source = pic
                                                                        }
                                                                })
                                                        } else {
                                                            contentSourceCheckMapper.insert(ContentSourceCheck()
                                                                .apply {
                                                                    appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                                        ?.let {
                                                                            createBy = it.id
                                                                            username = it.username
                                                                            userId = it.userId
                                                                            type = 2
                                                                            checkStatus = 3
                                                                            source = pic
                                                                            text = results.map { it.errorMsg }
                                                                                .joinToString(",")
                                                                        }
                                                                })
                                                            throw FlyException(results.map { it.errorMsg }
                                                                .joinToString(","))
                                                        }
                                                    }
                                                }
                                        }
                                    }
                                }
                            }

                        contentSourceCheckSettingMapper.selectOne(
                            KtQueryWrapper(ContentSourceCheckSetting::class.java)
                                .eq(ContentSourceCheckSetting::type, 1)
                                .last("limit 1")
                        )
                            ?.run {
                                if (this.open == true) {
                                    it.localTemplateUrl?.run {
                                        submitVideoCheck(this).let { submitResult ->
                                            if (submitResult.result == true) {
                                                this@apply.checkTaskId = submitResult.taskId

                                                contentSourceCheckMapper.insert(ContentSourceCheck()
                                                    .apply {
                                                        appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                            ?.let {
                                                                createBy = it.id
                                                                username = it.username
                                                                userId = it.userId
                                                                type = 1
                                                                taskId = submitResult.taskId
                                                                checkStatus = 1
                                                                source = videoChangeFaceDto.localTemplateUrl
                                                            }
                                                    })
                                            }
                                        }
                                    }
                                }
                            }

                        singleChangeFace = singleVideoPay == true
                        templateId = videoChangeFaceDto.templateId
                        functionId = functionService.getFaceId().first
                        hideWatermark = it.hideWatermark
                        param = com.alibaba.fastjson.JSON.toJSONString(it)
                        requestId = videoChangeFaceDto.templateId?.let { templateId ->
                            changeVideoFace(
                                videoChangeFaceDto,
                                templateService.getById(templateId).videoTemplateId,
                                templateService.getById(templateId).content
                            )
                        } ?: run {

                            apiType = globalParamDetailService.apiType(2, it.videoDuration)

                            when (apiType) {
                                1 -> changeVideoFace(
                                    videoChangeFaceDto,
                                    null,
                                    videoChangeFaceDto.localTemplateUrl
                                )

                                else -> {

                                    //调用火山api
                                    huoshanApi.videoSwapFace(VideoChangeFaceParam().apply {
                                        faceUrl = videoChangeFaceDto.referenceUrl
                                        videoUrl = videoChangeFaceDto.localTemplateUrl
                                        logo = videoChangeFaceDto.aiWatermark
                                    })
                                }
                            }

                        }
                        createBy = ProfileHolder.getProfile().id.toLong()


                    } catch (e: FlyException) {
                        status = 3
                        errorMsg = e.message
                    }

                }).takeIf { it }
                    ?.run {
                        if (userRecord.status != 3 && singleVideoPay == false && (videoChangeFaceDto.pay == true).not() && channelFreeTemplateMapper.selectOne(
                                KtQueryWrapper(ChannelFreeTemplate::class.java)
                                    .eq(
                                        ChannelFreeTemplate::channelId, channelManagerService.getOne(
                                            KtQueryWrapper(ChannelManager::class.java)
                                                .eq(ChannelManager::code, videoChangeFaceDto.channelCode)
                                        )?.id
                                    )
                                    .eq(ChannelFreeTemplate::templateId, videoChangeFaceDto.templateId)
                                    .eq(ChannelFreeTemplate::templateType, 1)
                            ) == null
                        ) {
                            appUserService.getById(ProfileHolder.getProfile().id)?.run {
                                if (appUserService.updateById(this.apply {
                                        changeFaceRemainCount = (changeFaceRemainCount ?: 0) + 1
                                    })) {
                                    userRecordService.updateById(userRecord.apply {
                                        usePoint = 1
                                    })
                                }
                            }
                        }

                        if (singlePicPay == true) {
                            appUserService.getById(ProfileHolder.getProfile().id)?.run {
                                appUserService.updateById(this.apply {
                                    singleChangeFaceCount = (singleChangeFaceCount ?: 0) + 1
                                })
                            }
                        }


                        if (userRecord.status == 2 && singleVideoPay == true) {

                            appUserService.getById(ProfileHolder.getProfile().id)?.run {
                                appUserService.updateById(this.apply {
                                    singleVideoPay = true
                                })
                            }
                        }





                        videoChangeFaceDto.templateId?.let {
                            templateService.getById(it)?.run {
                                templateService.updateById(this.apply {
                                    useNum = this.useNum?.plus(1)
                                })
                            }
                        }

                        //发送任务到延时队列
                        changeFaceTaskManager.addTask(userRecord.id!!)
                        true
                    }
            })

        }

    override fun singleTemplateMemberInfo(templateInfo: RecordApiService.TemplateInfo): Data<SingleTemplateMemberInfo?> {

        val templateNew = RecordApiService.TemplateInfo()
        templateInfo.templateId?.run {
            templateService.getById(this)?.let {
                templateNew.type = it.type
                templateNew.videoDuration = it.videoDuration
            } ?: throw FlyException("该模板不存在或者没有时长信息, 请重新上传该模板")
        } ?: run {
            templateNew.type = templateInfo.type
            templateNew.videoDuration = templateInfo.videoDuration
        }

        return when (templateNew.type) {
            1 -> Ok("获取视频单次收费信息成功", run {
                memberService.getOne(
                    KtQueryWrapper(Member::class.java)
                        .eq(Member::name, "视频单次收费")
                        .eq(Member::isShow, true)
                )
                    ?.let {
                        SingleTemplateMemberInfo().apply {
                            memberId = it.id
                            memberName = it.name
                            duration = durationDesc(templateNew.videoDuration ?: 0)
                            priceDesc = videoSinglePriceService.appPriceDesc(it.id!!, templateNew.videoDuration ?: 0)
                            price = "${videoSinglePriceService.priceCa(it.id!!, templateNew.videoDuration ?: 0)}"
                        }
                    }
            })

            else -> Ok("获取图片单次收费信息成功", run {
                memberService.getOne(
                    KtQueryWrapper(Member::class.java)
                        .eq(Member::name, "图片单次收费")
                        .eq(Member::isShow, true)
                )
                    ?.let {
                        SingleTemplateMemberInfo().apply {
                            memberId = it.id
                            memberName = it.name
                            price = "${it.price}"
                        }
                    }
            })
        }
    }

    override fun addUserPicChangeFace(imageChangeFaceDto: ImageChangeFaceDto): Data<Boolean> =

        appUserService.getById(ProfileHolder.getProfile().id).run {

            imageChangeFaceDto.aiWatermark = booleanAiWatermark(imageChangeFaceDto.channelCode!!)
            imageChangeFaceDto.softWatermark = booleanSoftWatermark(imageChangeFaceDto.channelCode!!)
            imageChangeFaceDto.hideWatermark = booleanHideWatermark(imageChangeFaceDto.channelCode!!)
            if (((imageChangeFaceDto.templateId
                    ?.run { templateCategoryService.isTest(templateService.getById(this)?.categoryId) } ?: false) == false)

            ) {

                if (StrUtil.isNotBlank(imageChangeFaceDto.localTemplateUrl) || channelFreeTemplateMapper.selectOne(
                        KtQueryWrapper(ChannelFreeTemplate::class.java)
                            .eq(
                                ChannelFreeTemplate::channelId, channelManagerService.getOne(
                                    KtQueryWrapper(ChannelManager::class.java)
                                        .eq(ChannelManager::code, imageChangeFaceDto.channelCode)
                                )?.id
                            )
                            .eq(ChannelFreeTemplate::templateId, imageChangeFaceDto.templateId)
                            .eq(ChannelFreeTemplate::templateType, 2)
                    ) == null
                ) {

                    if (singlePicPay == null || singlePicPay == false) {
                        if (userMemberService.getUserMemberByUserId(ProfileHolder.getProfile().id.toLong())?.endMemberDate?.year()
                                ?.let { it > 2100 } != true
                        ) {

                            if (booleanToll(imageChangeFaceDto.channelCode!!)) {
                                if ((imageChangeFaceDto.pay == true).not()) {
                                    if (userType != UserTypeEnum.MEMBER.code) {
                                        when (userType) {
                                            UserTypeEnum.NORMAL.code -> throw FlyException("换脸次数不足!")
                                            else -> throw FlyException("换脸次数不足!")
                                        }
                                    } else if ((totalChangeFaceCount ?: 0) - (changeFaceRemainCount ?: 0) <= 0) {
                                        throw FlyException("换脸次数不足!")
                                    }
                                }
                            }
                        }
                    }
                }

            }

            Ok("图片换脸成功", imageChangeFaceDto.let {

                val userRecord = UserRecord()
                userRecordService.save(userRecord.apply {
                    templateId = imageChangeFaceDto.templateId
                    functionId = functionService.getFaceId().second
                    createBy = ProfileHolder.getProfile().id.toLong()
                    singleChangeFace = singlePicPay == true
                    try {
                        status = 2

                        contentSourceCheckSettingMapper.selectOne(
                            KtQueryWrapper(ContentSourceCheckSetting::class.java)
                                .eq(ContentSourceCheckSetting::type, 2)
                                .last("limit 1")
                        )
                            ?.run {
                                if (this.open == true) {
                                    imageChangeFaceDto.imageUrl?.run {
                                        picContentCheck(this).let { results ->
                                            if (results.first().pass == true) {

                                                contentSourceCheckMapper.insert(
                                                    ContentSourceCheck()
                                                        .apply {
                                                            appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                                ?.let {
                                                                    createBy = it.id
                                                                    username = it.username
                                                                    userId = it.userId
                                                                    type = 2
                                                                    checkStatus = 2
                                                                    source = imageChangeFaceDto.imageUrl
                                                                }
                                                        })
                                            } else {

                                                contentSourceCheckMapper.insert(
                                                    ContentSourceCheck()
                                                        .apply {
                                                            appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                                ?.let {
                                                                    createBy = it.id
                                                                    username = it.username
                                                                    userId = it.userId
                                                                    type = 2
                                                                    checkStatus = 3
                                                                    source = imageChangeFaceDto.imageUrl
                                                                    text = results.map {
                                                                        it.errorMsg
                                                                    }.joinToString(",")
                                                                }
                                                        })

                                                throw FlyException(results.map {
                                                    it.errorMsg
                                                }.joinToString(","))
                                            }
                                        }
                                    }

                                    imageChangeFaceDto.localTemplateUrl?.run {
                                        picContentCheck(this).let { results ->
                                            if (results.first().pass == true) {

                                                contentSourceCheckMapper.insert(
                                                    ContentSourceCheck()
                                                        .apply {
                                                            appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                                ?.let {
                                                                    createBy = it.id
                                                                    username = it.username
                                                                    userId = it.userId
                                                                    type = 2
                                                                    checkStatus = 2
                                                                    source = imageChangeFaceDto.localTemplateUrl
                                                                }
                                                        })
                                            } else {

                                                contentSourceCheckMapper.insert(
                                                    ContentSourceCheck()
                                                        .apply {
                                                            appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                                ?.let {
                                                                    createBy = it.id
                                                                    username = it.username
                                                                    userId = it.userId
                                                                    type = 2
                                                                    checkStatus = 3
                                                                    source = imageChangeFaceDto.localTemplateUrl
                                                                    text = results.map {
                                                                        it.errorMsg
                                                                    }.joinToString(",")
                                                                }
                                                        })

                                                throw FlyException(results.map {
                                                    it.errorMsg
                                                }.joinToString(","))
                                            }
                                        }
                                    }

                                    imageChangeFaceDto.faces?.let { facesjson ->
                                        JSONUtil.parseArray(facesjson)
                                            .map {
                                                JSONUtil.parseObj(it).getStr("imageUrl")
                                                    ?.let { pic ->
                                                        picContentCheck(pic).let { results ->
                                                            if (results.first().pass == true) {

                                                                contentSourceCheckMapper.insert(
                                                                    ContentSourceCheck()
                                                                        .apply {
                                                                            appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                                                ?.let {
                                                                                    createBy = it.id
                                                                                    username = it.username
                                                                                    userId = it.userId
                                                                                    type = 2
                                                                                    checkStatus = 2
                                                                                    source = pic
                                                                                }
                                                                        })
                                                            } else {

                                                                contentSourceCheckMapper.insert(
                                                                    ContentSourceCheck()
                                                                        .apply {
                                                                            appUserService.getById(ProfileHolder.getProfile().id.toLong())
                                                                                ?.let {
                                                                                    createBy = it.id
                                                                                    username = it.username
                                                                                    userId = it.userId
                                                                                    type = 2
                                                                                    checkStatus = 3
                                                                                    source = pic
                                                                                    text = results.map {
                                                                                        it.errorMsg
                                                                                    }.joinToString(",")
                                                                                }
                                                                        })

                                                                throw FlyException(results.map {
                                                                    it.errorMsg
                                                                }.joinToString(","))
                                                            }
                                                        }
                                                    }
                                            }

                                    }
                                }
                            }

                        if (it.templateId == null) {
                            apiType = globalParamDetailService.apiType(1, null)

                            url = when (apiType) {
                                1 -> changePicFace(
                                    imageChangeFaceDto,
                                    templateService.getById(imageChangeFaceDto.templateId)?.picTemplateId
                                )?.run { netUrlUploadOss.upload(this) }

                                else -> {
                                    huoshanApi.picSwapFace(PicChangeFaceParam().apply {
                                        templateUrl = it.localTemplateUrl
                                        faceUrl = it.imageUrl
                                    })
                                }
                            }

                        } else {
                            url = changePicFace(
                                imageChangeFaceDto,
                                templateService.getById(imageChangeFaceDto.templateId)?.picTemplateId
                            )?.run { netUrlUploadOss.upload(this) }
                        }
                    } catch (e: FlyException) {
                        status = 3
                        errorMsg = e.message
                    }
                }).takeIf { it }
                    ?.run {

                        if (imageChangeFaceDto.hideWatermark == true) {
                            log.info("开始执行 图片隐形水印 生成")
                            userRecordService.updateById(userRecord.apply {
                                url = addTextWaterMark(aigc(userRecord.id!!, userRecord.createBy!!), this.url!!)
                            })
                        }

                        if (singlePicPay == false && (imageChangeFaceDto.pay == true).not() && channelFreeTemplateMapper.selectOne(
                                KtQueryWrapper(ChannelFreeTemplate::class.java)
                                    .eq(
                                        ChannelFreeTemplate::channelId, channelManagerService.getOne(
                                            KtQueryWrapper(ChannelManager::class.java)
                                                .eq(ChannelManager::code, imageChangeFaceDto.channelCode)
                                        )?.id
                                    )
                                    .eq(ChannelFreeTemplate::templateId, imageChangeFaceDto.templateId)
                                    .eq(ChannelFreeTemplate::templateType, 2)
                            ) == null
                        ) {
                            if (userRecord.status == 2) {
                                appUserService.getById(ProfileHolder.getProfile().id)?.run {
                                    appUserService.updateById(this.apply {
                                        changeFaceRemainCount = (changeFaceRemainCount ?: 0) + 1
                                    })
                                }
                            }
                        }

                        if (userRecord.status == 2 && singlePicPay == true) {
                            appUserService.getById(ProfileHolder.getProfile().id)?.run {
                                appUserService.updateById(this.apply {
                                    singlePicPay = false
                                })
                            }
                        }

                        if (singlePicPay == true) {
                            appUserService.getById(ProfileHolder.getProfile().id)?.run {
                                appUserService.updateById(this.apply {
                                    singleChangeFaceCount = (singleChangeFaceCount ?: 0) + 1
                                })
                            }
                        }
                        imageChangeFaceDto.templateId?.let {
                            templateService.getById(it)?.run {
                                templateService.updateById(this.apply {
                                    useNum = this.useNum?.plus(1)
                                })
                            }
                        }
                        true
                    }
            })
        }

    override fun addUserRecord(myRecordDto: MyRecordDto): Data<Boolean> =
        Ok("保存我的作品成功", kotlin.run {
            userRecordService.save(UserRecord().apply {
                BeanUtil.copyProperties(myRecordDto, this)
                createBy = ProfileHolder.getProfile().id.toLong()
            })
        })

    override fun removeUserRecord(ids: String): Data<Boolean> =
        Ok("移除我的作品成功", kotlin.run {
            ids.split(",")
                .takeIf { it.isNotEmpty() }
                ?.forEach {
                    userRecordService.getById(it.toLong())?.run {
                        userRecordService.updateById(this.apply {
                            deleteTime = Date()
                            deleteTag = 1
                        })
                    }
                }
            true
        })
}